package cn.youqu.happy.module.youqu.service.userArrange;

import cn.hutool.core.date.DateUtil;
import cn.youqu.happy.framework.common.pojo.PageResult;
import cn.youqu.happy.framework.common.util.string.StrUtils;
import cn.youqu.happy.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.youqu.happy.module.youqu.controller.admin.userArrange.vo.UserArrangeCreateReqVO;
import cn.youqu.happy.module.youqu.controller.admin.userArrange.vo.UserArrangeExportReqVO;
import cn.youqu.happy.module.youqu.controller.admin.userArrange.vo.UserArrangePageReqVO;
import cn.youqu.happy.module.youqu.controller.admin.userArrange.vo.UserArrangeUpdateReqVO;
import cn.youqu.happy.module.youqu.controller.app.userArrange.vo.AppUserArrangeUpdateReqVO;
import cn.youqu.happy.module.youqu.convert.userArrange.UserArrangeConvert;
import cn.youqu.happy.module.youqu.dal.dataobject.userArrange.UserArrangeDO;
import cn.youqu.happy.module.youqu.dal.mysql.userArrange.UserArrangeMapper;
import cn.youqu.happy.module.youqu.enums.userArrange.UserArrangeStatusEnum;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static cn.youqu.happy.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.youqu.happy.module.youqu.enums.ErrorCodeConstants.USER_ARRANGE_NOT_EXISTS;

/**
 * 用户计划 Service 实现类
 *
 * @author 王其岩 20112001045
 */
@Service
@Validated
public class UserArrangeServiceImpl implements UserArrangeService {

    @Resource
    private UserArrangeMapper userArrangeMapper;

    /**
     * 每5分钟自动更新一次互动状态
     */
    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;

    @Override
    public Integer createUserArrange(UserArrangeCreateReqVO createReqVO) {
        // 插入
        //判断活动安排 是否存在
        if (this.getUserArrange0(createReqVO.getActivityId()) == null) {
            UserArrangeDO userArrange = UserArrangeConvert.INSTANCE.convert(createReqVO);
            System.out.println(userArrange.getPartners());
            userArrangeMapper.insert(userArrange);
            // 返回
            return userArrange.getId();
        }
        //已经创建活动安排 返回 -1
        return -1;
    }

    @Override
    public void updateUserArrange(UserArrangeUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateUserArrangeExists(updateReqVO.getId());
        // 更新
        UserArrangeDO updateObj = UserArrangeConvert.INSTANCE.convert(updateReqVO);
        userArrangeMapper.updateById(updateObj);
    }

    @Override
    public void updateUserArrange(AppUserArrangeUpdateReqVO updateReqVO, Long uid) {
        // 校验存在
        this.validateUserArrangeExists(updateReqVO.getId(), uid);
        // 更新
        UserArrangeConvert.INSTANCE.convert(updateReqVO);
        UserArrangeDO updateObj = UserArrangeConvert.INSTANCE.convert(updateReqVO);
        userArrangeMapper.updateById(updateObj);
    }


    @Override
    public void deleteUserArrange(Integer id) {
        // 校验存在
        this.validateUserArrangeExists(id);
        // 删除
        userArrangeMapper.deleteById(id);
    }


    /**
     * 校验是否存在
     *
     * @param id
     */
    private void validateUserArrangeExists(Integer id) {
        if (userArrangeMapper.selectById(id) == null) {
            throw exception(USER_ARRANGE_NOT_EXISTS);
        }
    }

    @Override
    public boolean validateUserOwnUserArrange(Integer id, Long partner) {
        UserArrangeDO userArrangeDO = userArrangeMapper.selectById(id);
        if (userArrangeDO == null) {
            throw exception(USER_ARRANGE_NOT_EXISTS);
        } else if (partner.equals(userArrangeDO.getUid())) {
            return true;
        } else if (userArrangeDO.getPartners() != null) {
            String partners = userArrangeDO.getPartners();
            List<String> partnerArr = StrUtils.stringConvertToList(partners);
            return partnerArr.stream().anyMatch(item -> String.valueOf(partner).equals(item));
        } else {
            throw exception(USER_ARRANGE_NOT_EXISTS);
        }
    }

    @Override
    @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
    public void autoUpdateUserArrangeStatus() {
        //TODO 还有10分钟到期自动提醒
        //TODO 到期自动更新活动状态
        //TODO 活动结束推送发布评价和说说的通知 暂时不添加结束时间
        LambdaQueryWrapperX<UserArrangeDO> queryWrapperX = new LambdaQueryWrapperX<>();
        queryWrapperX.ne(UserArrangeDO::getArrangeStatus, UserArrangeStatusEnum.ARRANGE_CANCEL.getStatus());
        queryWrapperX.between(UserArrangeDO::getStartDate, DateUtil.offsetMinute(new Date(), -5), DateUtil.offsetMinute(new Date(), 5));
        List<UserArrangeDO> userArrangeDOS = userArrangeMapper.selectList(queryWrapperX);
        userArrangeDOS.forEach(item -> {
            //当前时间小于开始时间
            if (new Date().compareTo(item.getStartDate()) < 0) {
                //推送任务提醒
            } else if (new Date().compareTo(item.getStartDate()) >= 0) {
                item.setArrangeStatus(UserArrangeStatusEnum.ARRANGE_ING.getStatus());
                //更新活动状态
                userArrangeMapper.updateById(item);
            }
        });
    }

    /**
     * 校验是否为发起人
     *
     * @param id
     * @param uid
     */
    private void validateUserArrangeExists(Integer id, Long uid) {
        if (userArrangeMapper.findOneByIdAndUid(id, uid) == null) {
            throw exception(USER_ARRANGE_NOT_EXISTS);
        }
    }


    @Override
    public UserArrangeDO getUserArrange(Integer id) {
        return userArrangeMapper.selectById(id);
    }

    @Override
    public UserArrangeDO getUserArrange(Integer id, Long uid) {
        boolean b = validateUserOwnUserArrange(id, uid);
        if (b) {//拥有此计划
            return userArrangeMapper.selectById(id);
        }
        return null;
    }

    @Override
    public UserArrangeDO getUserArrange0(Integer activityId) {
        return userArrangeMapper.findOneByActivityId(activityId);
    }

    @Override
    public List<UserArrangeDO> getUserArrangeList(Collection<Integer> ids) {
        return userArrangeMapper.selectBatchIds(ids);
    }


    /**
     * 筛选用户是发起人或者 用户是队员
     *
     * @param userArrangeDOS
     * @param uid
     * @return
     */
    private List<UserArrangeDO> filterUserCanSeeUserArrange(List<UserArrangeDO> userArrangeDOS, Long uid) {
        return userArrangeDOS.stream().filter(item -> {
            if (uid.equals(item.getUid())) {
                return true;
            } else if (item.getPartners() != null) {
                List<String> partnerArr = StrUtils.stringConvertToList(item.getPartners());
                return partnerArr.stream().anyMatch(item1 -> String.valueOf(uid).equals(item1));
            } else {
                return false;
            }
        }).collect(Collectors.toList());
    }

    @Override
    public List<UserArrangeDO> getUserArrangeList(Collection<Integer> ids, Long uid) {
        List<UserArrangeDO> userArrangeDOS = userArrangeMapper.selectBatchIds(ids);
        return filterUserCanSeeUserArrange(userArrangeDOS, uid);
    }

    @Override
    public PageResult<UserArrangeDO> getUserArrangePage(UserArrangePageReqVO pageReqVO) {
        return userArrangeMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<UserArrangeDO> getUserArrangePage(UserArrangePageReqVO pageReqVO, Long uid) {
        PageResult<UserArrangeDO> userArrangeDOPageResult = userArrangeMapper.selectPage(pageReqVO);
        List<UserArrangeDO> list = userArrangeDOPageResult.getList();

        //筛选用户在计划内的
        List<UserArrangeDO> collect = filterUserCanSeeUserArrange(list, uid);

        userArrangeDOPageResult.setList(collect);
        userArrangeDOPageResult.setTotal(Long.valueOf(collect.size()));
        return userArrangeDOPageResult;
    }

    @Override
    public List<UserArrangeDO> getUserArrangeList(UserArrangeExportReqVO exportReqVO) {
        return userArrangeMapper.selectList(exportReqVO);
    }

//    @Override
//    public boolean cancelUserArrange(Integer id, Long loginUserId) {
//        // 校验存在
//        this.validateUserArrangeExists(id, loginUserId);
//
//        //TODO 发起安排编辑申请
//        return false;
//    }

}
